#include "http_hand.h"
#include <cstdio>
#include <cstring>
#include <strings.h>
#include <sys/sendfile.h>
#include <sys/socket.h>
#include <unistd.h>
static void clear_handler(int sfd){
		char buf[SIZE];
		int ret=0;
		do {
			ret=get_line(sfd,buf);
		}while (ret!=1&&strcmp(buf,"\n")!=0);
}
static void show_404(int sfd){
	//将获得的信息全部抹去（清空缓冲区），因为之前只读取了首部
	clear_handler(sfd);
	char buf[SIZE]="HTTP/1.1 404 Not Found\r\n";//响应报文首部
	send(sfd,buf,strlen(buf),0);
	//打开一个html页面文档
	struct stat st;
	stat("/home/rayfilewed/html/404.html",&st);
	int fd=open("/home/rayfileweb/html/404.html",O_RDONLY);
	if(fd==-1){
		perror("open 404 error");
		return;
	}
	char Content_Length[SIZE];
	sprintf(Content_Length,"Content-Length: %zu\r\n",st.st_size);
	send(sfd,Content_Length,strlen(Content_Length),0);
	send(sfd, "\r\n", strlen("\r\n"), 0);
	//将整个文件发送出去
	//参数3：起始位置（NULL表示从文件起始位置拷贝）
	//参数4：表示拷贝多少
	sendfile(sfd,fd,NULL,st.st_size);
}
void echo_error(int sfd,int mode){
	switch (mode) {
		case 404:
				show_404(sfd);
				break;
		default:
				show_404(sfd);
				break;
	}
}
void echo_www(int sfd,char path[],size_t fsize){
	//将获得的信息全部抹去（清空缓冲区），因为之前只读取了首部
	clear_handler(sfd);
	char hand[SIZE];
	sprintf(hand,"HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Length: %zu\r\n",fsize);
	send(sfd,hand,strlen(hand),0);
	send(sfd, "\r\n", strlen("\r\n"), 0);
	//打开一个html页面文档
	int fd=open(path,O_RDONLY);
	if(fd==-1){
		perror("open fd");
		return;
	}
	if(sendfile(sfd,fd,NULL,fsize)==-1){
		close(fd);
		echo_error(sfd,500);
		return;
	}
	cout<<"GET SUCESS"<<endl;
	close(fd);
	return;
}
void handler_request(int sfd,char method [],char path [],char querry_string []){
	char line[SIZE];//存储一行数据
	int ret=0;
	int content_len=0;	//接收消息的内容长度
	bool is_upload=false;//判断是不是上传请求
	char boundary[SIZE]="";
	if (strcasecmp(method,"GET")==0) {
		clear_handler(sfd);
	}else {
		//POST请求
		//获取请求的信息
		do {
			recv(sfd,line,1,0);
			ret=get_line(sfd,line);//读取一行信息
			if (strncasecmp(line,"content-length",14)==0) {
				//说明有消息可以处理
				content_len=atoi(line+16);
			}
			if (strncasecmp(line,"Content-Type",12)==0&&is_upload==false) {
				if ((strstr(line,"multipart/form-data;"))) {
					is_upload=true;
					strcpy(boundary,strstr(line,"boundary=")+strlen("boundary="));
					boundary[strlen(boundary)-1]=0;
				}
			}
		}while (ret!=1&&(strcmp(line,"\n")!=0));
	}
	recv(sfd,line,1,0);
	printf("method:%s\n",method);
	printf("querry_string:%s\n",querry_string);
	printf("content_len:%d\n",content_len);
	char req_buf[SIZE]={0};//处理数据的缓冲区
	//如果是非下载的POST方法，肯定会携带数据，那么我们要将数据解析出来
	if (is_upload) {
		//先发送状态码
		const char *hand="HTTP/1.1 200 OK\r\nConnection: close\r\n";
		send(sfd,hand,strlen(hand),0);
		upload(sfd,boundary);
	}
	else{
		if (strcasecmp(method,"POST")==0) {
			int len=recv(sfd,req_buf,content_len,0);
			printf("len:%d\n",len);
			printf("buf:%s\n",req_buf);
		}
		//先发送状态码
		const char *hand="HTTP/1.1 200 OK\r\nConnection: close\r\n";
		send(sfd,hand,strlen(hand),0);
		//将请求交给自定义的代码来处理
		persa_and_process(sfd,querry_string,req_buf);
	}
}
